
import { useEffect, useState } from 'react';
import './ColorSelect.less'
import { ColorAxis, ColorSystemFormat, ModelFormat, themeManager, UI_MODEL } from './ColorUtil';


const SQUARE_SIZE = 400;
const CIRCLE_RADIUS = 115;
const DOT_SIZE = 14;

function ColorSelect() {
    // 当前选中的颜色值
    const [activeStyle, setActiveStype] = useState({
        backgroundColor: '#fff'
    })
    // 色轮中的圆点位置与大小
    const [dotStyle, setDotStyle] = useState({
        width: `${DOT_SIZE}px`,
        height: `${DOT_SIZE}px`,
        left: `-200px`,
        top: `-200px`
    })
    // 色轮的中心位置
    const [circleCenter, setCircleCenter] = useState({
        x: 0, y: 0
    })

    // 亮度、饱和度样式确认
    const [alphaContainer, setAlphaContainer] = useState({
        dotStyle: {
            width: `${DOT_SIZE}px`,
            height: `${DOT_SIZE}px`,
            left: -100,
            top: -100,
        },
        boxStyle: {},
    })
    // 亮度box位置属性
    const [alphaBoxRect, setAlphaBoxRect] = useState({
        x: -1, y: -1, width: -1, height: -1
    })

    // 系统色系输出
    const [colorSystem, setColorSystem] = useState<ColorSystemFormat>({
        H: 0,
        dS: 0,
        dV: 1,
        model: 1,
        UIPlan: {
            title: '配色方案',
            colorList: [],
        },
        baseColor: {
            title: '基础色：',
            colorList: [],
        }
    })


    // 拖拽或点击圆点，选择指定的颜色
    const dragHueDot = (evt: any) => {
        let dx = evt.clientX - circleCenter.x;
        let dy = circleCenter.y - evt.clientY;
        let deg = Math.atan2(dy, dx);
        let rad = Math.round(deg * 180 / Math.PI)
        changeDeg(rad);
    }

    // 拖拽亮度饱和度圆点
    const dragAlphaDot = (evt: any) => {

        let { clientX, clientY } = evt;
        let boxRect: any = alphaBoxRect;
        if (clientX < boxRect.x) {
            clientX = boxRect.x;
        }
        if (clientX > boxRect.x + boxRect.width) {
            clientX = boxRect.x + boxRect.width;
        }
        if (clientY < boxRect.y) {
            clientY = boxRect.y;
        }
        if (clientY > boxRect.y + boxRect.height) {
            clientY = boxRect.y + boxRect.height;
        }
        let s, v;
        s = (clientX - boxRect.x) / boxRect.width;
        v = (clientY - boxRect.y) / boxRect.height;
        changeSV(s, v);
    }

    // 修改亮度和饱和度
    const changeSV = (ds: any, dv: any) => {
        let boxRect: any = alphaBoxRect;
        let x = boxRect.x + boxRect.width * ds;
        let y = boxRect.y + boxRect.height * dv;

        setAlphaContainer({
            ...alphaContainer,
            dotStyle: {
                ...alphaContainer.dotStyle,
                left: x - DOT_SIZE / 2,
                top: y - DOT_SIZE / 2,
            }
        })

        // TODO:待解析
        const b = ds - 0.5, e = 0.5 - dv;
        setColorSystem({
            ...colorSystem,
            dS: b > 0.4 ? (b - 0.4) / 0.1 : (b + 0.5) / 0.9 - 1,
            dV: e > 0.4 ? (e - 0.4) / 0.1 : (e + 0.5) / 0.9 - 1

            // dS: (ds - 0.4) / 0.5,
            // dV: (0.4 - dv) / 0.5
        })
    }

    // 色轮中圆点选的角度变化
    // rad为以x正半轴起始，逆时针取得角度。
    const changeDeg = (rad: number) => {
        let deg = rad * Math.PI / 180;
        // hsv为以y轴正半轴为起点，顺时针方向的角度，取颜色的色调值。
        let hsv = 0;
        if (rad > 90) {
            hsv = 270 + 180 - rad;
        } else {
            hsv = 90 - rad;
        }

        // 移动选中的圆点
        setDotStyle({
            ...dotStyle,
            top: circleCenter.y - CIRCLE_RADIUS * Math.sin(deg) - DOT_SIZE / 2 + 'px',
            left: circleCenter.x + CIRCLE_RADIUS * Math.cos(deg) - DOT_SIZE / 2 + 'px'
        })
        // 设置当前选择的颜色
        setColorSystem({
            ...colorSystem,
            H: hsv
        })
    }
    useEffect(() => {
        rendercolor();
    }, [colorSystem.H, colorSystem.dS, colorSystem.dV])

    const getSchemodel = (model: number): ModelFormat => {
        return UI_MODEL[`m${model}`]
    }

    // 绘制页面处理函数
    const rendercolor = () => {
        // 注意Dist值的内容
        var b = getSchemodel(colorSystem.model).getH(colorSystem.H, 30);
        let contrastModel = themeManager.get(0.5, 0.5);
        let conversion = 0;
        let varsOverlay = [[], [], [], []];

        // a始终为undefined，此分支一直都走。
        let Primary = new ColorAxis(colorSystem.H, colorSystem.dS, colorSystem.dV, contrastModel, varsOverlay[0], conversion);
        let Compl = b.C == void 0 ? null : new ColorAxis(b.C, colorSystem.dS, colorSystem.dV, contrastModel, varsOverlay[3], conversion);

        let Sec1 = b.S1 == void 0 ? null : new ColorAxis(b.S1, colorSystem.dS, colorSystem.dV, contrastModel, varsOverlay[1], conversion);
        let Sec2 = b.S2 == void 0 ? null : new ColorAxis(b.S2, colorSystem.dS, colorSystem.dV, contrastModel, varsOverlay[2], conversion)

        const uiColorIdx = [0, 3, 4, 2];
        const uiPlanColorList = uiColorIdx.map(item => Primary.Col[item].RGB);

        const baseColorList = Primary.Col.map(item => item.RGB)
        setColorSystem(Object.assign(colorSystem, {
            UIPlan: {
                ...colorSystem.UIPlan,
                colorList: [...uiPlanColorList]
            },
            baseColor: {
                ...colorSystem.baseColor,
                colorList: [...baseColorList]
            }
        }))
        setActiveStype({
            backgroundColor: uiPlanColorList[0].getCSS()
        })
        setAlphaContainer(Object.assign(alphaContainer, {
            boxStyle: {
                backgroundColor: Primary.Base.RGB.getCSS()
            }
        }))
    }

    // 初始化操作
    useEffect(() => {
        let dom02 = document.querySelector('#alpha-box');
        let client01 = dom02?.getClientRects();
        if (client01) {
            let boxRect = {
                x: client01[0].left,
                y: client01[0].top,
                width: client01[0].width,
                height: client01[0].width,
            }
            setAlphaBoxRect(boxRect)
        }


        // 色轮dom渲染后，拿到圆心的坐标
        let dom = document.querySelector('#color-wheel-box');
        let circleCenter = { x: 0, y: 0 };
        let client = dom?.getClientRects();
        if (client) {
            circleCenter.x = client[0].left + SQUARE_SIZE / 2
            circleCenter.y = client[0].top + SQUARE_SIZE / 2
            setCircleCenter(circleCenter);
        }
    }, [])



    // 圆心确定后，所有角度颜色初始化
    useEffect(() => {
        changeDeg(90);
        // rendercolor();
    }, [circleCenter])

    // 饱和度四方格确定后，饱和度圆点初始化
    useEffect(() => {
        changeSV(1, 0);
    }, [alphaBoxRect])

    // 窗口改变大小后，重新渲染
    // window.onresize = () => {
    //     changeDeg(90);
    //     changeSV(1, 0);
    // }

    return (
        <div className="m-color-select">
            <div className="m-color-select__title">颜色筛选</div>
            <div id="color-wheel-box" className="m-color-select__color-wheel" onMouseDown={dragHueDot}>
                <div className="color-wheel color-wheel--1"></div>
                <div className="color-wheel color-wheel--2"></div>
                <div className="color-wheel color-wheel--3"></div>
                <div className="color-wheel color-wheel--4"></div>
                <div className="color-wheel--active" style={activeStyle}></div>
                <div className="color-wheel__dot-1" style={dotStyle}></div>
            </div>
            <div className="m-alpha-select">
                <div className="m-color-select__title">透明度选择</div>
                <div id="alpha-box" className="alpha-box" style={alphaContainer.boxStyle} onMouseDown={dragAlphaDot}>
                    <div className="alpha-cover">
                        <div className="alpha-dot" style={alphaContainer.dotStyle}></div>
                    </div>
                </div>
            </div>
            <div className="output-color">
                {[colorSystem.UIPlan, colorSystem.baseColor].map(item => {
                    return (
                        <div key={item.title} className="output-container">
                            <div className='plan-title'>{item.title}</div>
                            <div className='color-box'>
                                {item.colorList.map((rgbItem, rgbIdx) => {
                                    return (
                                        <div key={'rgb' + rgbIdx} style={{ backgroundColor: rgbItem.getCSS() }} className="plan-item">#{rgbItem.getHex()}</div>
                                    )
                                })}
                            </div>
                        </div>
                    )
                })}

            </div>
            {/* <div>{JSON.stringify(alphaContainer)}</div> */}
        </div>
    )
}

export default ColorSelect;

